//
//  AccountService.swift
//  RxStudy
//
//  Created by season on 2021/6/1.
//  Copyright © 2021 season. All rights reserved.
//

import Foundation
import RxSwift
import Moya
import MoyaSugar
import SVProgressHUD

enum AccountService {
    case login(_ username: String, _ password: String, _ showLoading: Bool)
    case register(_ username: String, _ password: String, _ repassword: String)
    case logout
}

extension AccountService: TargetType {
    
    var baseURL: URL {
        return URL(string: Api.baseUrl)!
    }
    
    var path: String {
        switch self {
        case .login:
            return Api.Account.login
        case .register:
            return Api.Account.register
        case .logout:
            return Api.Account.logout
        }
    }
    
    var method: Moya.Method {
        switch self {
        case .logout:
            return .get
        default:
            return .post
        }
    }
    
    var sampleData: Data {
        return Data()
    }
    
    var task: Task {
        switch self {
        case .login(let username, let password, _):
            return .requestParameters(parameters: ["username": username, "password": password], encoding: URLEncoding.default)
        case .register(let username, let password, let repassword):
            return .requestParameters(parameters: ["username": username, "password": password, "repassword": repassword], encoding: URLEncoding.default)
        case .logout:
            return .requestParameters(parameters: .empty, encoding: URLEncoding.default)
            
        }
        
    }
    
    var headers: [String : String]? {
        switch self {
        case .login(_, _, let showLoading):
            return ["showLoading": "\(showLoading)"]
        default:
            return nil
        }
        
    }
}

extension AccountService: SugarTargetType {
    
    var route: MoyaSugar.Route {
        switch self {
        case .login:
            return .post(Api.Account.login)
        case .register:
            return .post(Api.Account.register)
        case .logout:
            return .get(Api.Account.logout)
        }
    }
    
    var parameters: MoyaSugar.Parameters? {
        switch self {
        case .login(let username, let password, _):
            return ["username": username, "password": password]
        case .register(let username, let password, let repassword):
            return ["username": username, "password": password, "repassword": repassword]
        case .logout:
            return nil
        }
    }
}

protocol LoginServiceType {
    
    func login(name: String, pwd: String) -> Observable<Bool>
    func registerAndLogin(name: String, pwd: String, rePwd: String) -> Observable<Bool>
    func logout() -> Observable<Void>
}

class LoginService: LoginServiceType {
    
    let networking = Networking<AccountService>(plugins: [])
    
    func login(name: String, pwd: String) -> Observable<Bool> {
        return networking
            .request(.login(name, pwd, true))
            .map(BaseModel<AccountInfo>.self)
            .do(onSuccess: { info in
                if !info.isSuccess {
                    DispatchQueue.main.async {
                        SVProgressHUD.showText(info.errorMsg ?? "登录失败")
                    }
                }
            })
            .asObservable()
            .map {$0.isSuccess}
            .catchAndReturn(false)
    }
    
    func registerAndLogin(name: String, pwd: String, rePwd: String) -> Observable<Bool> {
        return networking
            .request(.register(name, pwd, rePwd))
            .map(BaseModel<AccountInfo>.self)
            .do { info in
                if info.isSuccess {
                    DispatchQueue.main.async {
                        SVProgressHUD.showText("注册成功")
                    }
                }
            }
            .asObservable()
            .flatMap {_ in self.login(name: name, pwd: pwd)}
    }
    
    func logout() -> Observable<Void> {
        return networking
            .request(.logout)
            .asObservable()
            .map {_ in }
    }
    
}
